﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using KGE.BasicCOM;
using KGE.Define;
using KGE.Resource;

namespace KGE
{
    public class Game : IDisposable
    {
        #region 执行模板
        /// <summary>
        /// peek_message - Native windows message structure. Not actually used, but
        ///   PeekMessage requires that it be passed in
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        struct peek_message
        {
            public IntPtr hWnd;
            public Message msg;
            public IntPtr wParam;
            public IntPtr lParam;
            public uint time;
            public System.Drawing.Point p;
        }
        /// <summary>
        /// PeekMessage - Checks if messages are waiting in the queue. No parameters are
        ///   actually used.
        /// </summary>
        /// <param name="msg">not used</param>
        /// <param name="hWnd">not used</param>
        /// <param name="messageFilterMin">not used</param>
        /// <param name="messageFilterMax">not used</param>
        /// <param name="flags">not used</param>
        /// <returns></returns>
        [System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        static extern bool PeekMessage(out peek_message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);
        /// <summary>
        /// AppIsIdle - Tests to see if there are messages that need processing, or if the
        ///   application is idle.
        /// </summary>
        bool ApplicationIsIdle
        {
            get
            {
                peek_message msg;
                return !PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
            }
        }
        /// <summary>
        /// OnApplicationIdle - This function is to be bound to the application
        ///   idle event. As long as there are no messages waiting in the queue
        ///   it will call Heartbeat as fast as it can
        /// </summary>
        /// <param name="sender">not used</param>
        /// <param name="e">not used</param>
        void OnApplicationIdle(object sender, EventArgs e)
        {
            while (ApplicationIsIdle && !isExited)
            {
                Heartbeat();
            }
        }
        #endregion

        #region 构造方法
        public Game()
            : this("noname")
        { }

        public Game(string name)
            : this(name, new Form())
        {
        }
        public Game(Control control)
            : this("noname", control)
        { }
        public Game(string name, Control control)
        {
            GameControl = control;
            Name = name;
            Options = new Options();
            try
            {
                Options = (Options)Util.LoadObjectXML("options.xml", typeof(Options));
            }
            catch { }
            Devices = new Devices(this);
        }
        #endregion

        #region 属性
        public double FPS
        {
            get
            {
                double fps = 1 / Devices.Timer.Seconds;
                if (fps > FPSMax)
                {
                    if (RunningTotalSeconds > 1)
                    {
                        FPSMax = fps;
                    }
                }
                if (fps < FPSMin)
                {
                    if (RunningTotalSeconds > 1)
                    {
                        FPSMin = fps;
                    }
                }
                return fps;
            }
        }
        public double RunningTotalSeconds
        {
            get
            {
                return Devices.Timer.TotalSeconds;
            }
        }
        //public string IconFileName
        //{
        //    set
        //    {
        //        Devices.GameWindow.Icon = new Icon(value);
        //    }
        //}
        public string KeyStreamText
        {
            get
            {
                return KeyboardCOM.ToString();
            }
        }
        public bool KeyboardIsIdle
        {
            get
            {
                return KeyboardCOM.IsIdle;
            }
        }
        #endregion

        #region 私有字段
        bool isExited = false;
        bool isRunning = false;
        bool NeedCPUDraw = false;
        bool NeedCPUClear = false;
        KeyboardCOM KeyboardCOM;
        SceneCOM SceneCOM;
        #endregion

        #region 公有字段
        public Control GameControl;
        public string Name;
        public Options Options;
        public Devices Devices;
        public KImages KImages;
        public KMovies KMovies;
        public KImagePackages KImagePackages;

        //public Textures Textures;



        public List<GameCOM> GameComs = new List<GameCOM>();
        public Scene Scene;

        public double FPSMax = 10;
        public double FPSMin = 60;
        #endregion

        #region 私有方法

        //void clearSurf()
        //{
        //    if (NeedCPUClear)
        //    {
        //        //CPUClear();
        //        NeedCPUClear = false;
        //    }
        //}
        //void drawSurf()
        //{
        //    if(NeedCPUDraw)
        //    {
        //        using (Texture texture = new Texture(Devices.D3DDev, Options.WindowSizePixel.Width, Options.WindowSizePixel.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed))
        //        {
        //            using (Graphics g = texture.GetSurfaceLevel(0).GetGraphics())
        //            {
        //                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
        //                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
        //                //g.DrawImage(Devices.Surface, new Point());
        //            }
        //            //GPUDrawTexture(texture, Color.White,, new Vector3());
        //        }              
        //        //GPUDrawImage(Devices.Surface, Color.White, new Vector3());
        //        NeedCPUDraw = false;
        //    }
        //}
        void initCOM()
        {
            KeyboardCOM = new KeyboardCOM(this);
            MountGameCOM(KeyboardCOM);

            SceneCOM = new SceneCOM(this);
            MountGameCOM(SceneCOM);
        }
        void initDAT()
        {
        }
        void intiRES()
        {
            KImages = new KImages();
            KMovies = new KMovies();
            KImagePackages = new KImagePackages();

            LoadAllKI(Options.RootPath);
            LoadAllKM(Options.RootPath);
            LoadAllKIP(Options.RootPath);
        }
        void frame()
        {
            Devices.Timer.Record();
            Devices.Timer.Reset();


            Devices.GPU.Clear();
            //clearSurf(); 

            foreach (GameCOM gameCOM in GameComs)
            {
                gameCOM.BaseCode();
                if (gameCOM.Enable)
                {
                    gameCOM.Code();
                }
                if (gameCOM.Visible)
                {
                    gameCOM.Draw();
                }
            }

            Devices.GPU.Present();
            //drawSurf();
        }
        void init()
        {
            initDAT();
            intiRES();
            initCOM();
            //Devices.Surface = new Bitmap(Options.WindowSizePixel.Width, Options.WindowSizePixel.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        }
        void goFullScreen()
        {
            if (GameControl is Form)
            {
                ((Form)GameControl).TopMost = true;
                HideWindowBorder();

                Devices.GPU.Windowed = false;
                Devices.GPU.Reset();
            }
        }
        void goWindowed()
        {
            if (GameControl is Form)
            {
                Devices.GPU.Windowed = true;
                Devices.GPU.Reset();

                ((Form)GameControl).TopMost = false;
                if (Options.IsShowWindowBorder)
                {
                    ShowWindowBorder();
                }
                else
                {
                    HideWindowBorder();
                }
            }
        }
        #endregion

        #region 公有方法
        /// <summary>
        /// 挂载MetalX组件
        /// </summary>
        /// <param name="metalXCom"></param>
        public void MountGameCOM(GameCOM gameCom)
        {
            GameComs.Add(gameCom);
        }
        public void Heartbeat()
        {
            //if (Devices.D3DDev.Disposed)
            //{
            //    return;
            //}
            if (Options.IsFullScreen == Devices.GPU.Windowed)
            {
                if (Options.IsFullScreen)
                {
                    goFullScreen();
                }
                else
                {
                    goWindowed();
                }
            }
            if (isRunning)
            {
                frame();
            }
            //int result;
            //if (Devices.D3DDev.CheckCooperativeLevel(out result))
            //{
            //    //Okay to render
            //    try
            //    {
            //        frame();
            //    }
            //    catch (DeviceLostException)
            //    {
            //        Devices.D3DDev.CheckCooperativeLevel(out result);
            //    }
            //    catch (DeviceNotResetException)
            //    {
            //        Devices.D3DDev.CheckCooperativeLevel(out result);
            //    }
            //}
            //if (result == (int)ResultCode.DeviceLost)
            //{
            //    System.Threading.Thread.Sleep(500);    //Can't Reset yet, wait for a bit
            //}
            //else if (result == (int)ResultCode.DeviceNotReset)
            //{
            //    Devices.D3DDev.Reset(Devices.D3DDev.PresentationParameters);
            //}
        }

        public void ShowWindowBorder()
        {
            GameControl.Hide();
            ((Form)GameControl).FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
            GameControl.Show();
        }
        public void HideWindowBorder()
        {
            GameControl.Hide();
            ((Form)GameControl).FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            GameControl.Show();
        }

        public void SwitchFW()
        {
            Options.IsFullScreen = !Options.IsFullScreen;
        }
        public void Start()
        {
            init();
            isRunning = true;

            Application.Idle += new EventHandler(OnApplicationIdle);

            if (GameControl is Form)
            {
                Application.Run((Form)GameControl);
            }

            //Devices.GameWindow.Show();
            //while (isRunning)
            //{
            //    Heartbeat();
            //    Application.DoEvents();
            //}
        }
        public void Pause()
        {
            isRunning = false;
        }
        public void Dispose()
        {
            Devices.Dispose();
        }
        public void Exit()
        {
            isRunning = false;
            isExited = true;
            Dispose();
            Util.SaveObjectXML("options.xml", Options);
            Application.Exit();
        }
        public void LoadKScene(string pathName)
        {
            Scene = (Scene)Util.LoadObject(pathName);
        }
        public void LoadAllKI(string pathName)
        {
            List<string> dirName = new List<string>();
            Util.EnumDir(pathName, dirName);
            foreach (string pName in dirName)
            {
                DirectoryInfo di = new DirectoryInfo(pName);
                FileInfo[] fis = di.GetFiles("*.ki");
                foreach (FileInfo fi in fis)
                {
                    KImage item = (KImage)Util.LoadObject(fi.FullName);
                    item.Texture = Devices.GPU.KImage2Texture(item);
                    KImages.Add(item);
                }
            }
        }
        public void LoadAllKM(string pathName)
        {
            List<string> dirName = new List<string>();
            Util.EnumDir(pathName, dirName);
            foreach (string pName in dirName)
            {
                DirectoryInfo di = new DirectoryInfo(pName);
                FileInfo[] fis = di.GetFiles("*.km");
                foreach (FileInfo fi in fis)
                {
                    KMovie item = (KMovie)Util.LoadObject(fi.FullName);
                    for (int i = 0; i < item.Frames.Count; i++)
                    {
                        item.Frames[i].KImage.Texture = Devices.GPU.KImage2Texture(item.Frames[i].KImage);
                    }
                    KMovies.Add(item);
                }
            }
        }
        public void LoadAllKIP(string pathName)
        {
            List<string> dirName = new List<string>();
            Util.EnumDir(pathName, dirName);
            foreach (string pName in dirName)
            {
                DirectoryInfo di = new DirectoryInfo(pName);
                FileInfo[] fis = di.GetFiles("*.kip");
                foreach (FileInfo fi in fis)
                {
                    KImagePackage item = (KImagePackage)Util.LoadObject(fi.FullName);
                    for (int i = 0; i < item.Count; i++)
                    {
                        item[i].Texture = Devices.GPU.KImage2Texture(item[i]);
                    }
                    KImagePackages.Add(item);
                }
            }
        }

        public void DrawText(string text, Color color, Vector3 v3)
        {
            Devices.GPU.DrawText(text, color, v3);
        }
        public void DrawRectangle(Color color, Rectangle rect)
        {
            Devices.GPU.DrawRectangle(color, rect);
        }

        public void DrawKImage(ObjectIndexer oi, Vector3 v3)
        {
            DrawKImage(oi, Color.White, v3);
        }
        public void DrawKImage(ObjectIndexer oi, Color filterColor, Vector3 v3)
        {
            if (oi.Index < 0)
            {
                oi.Index = KImages.GetIndex(oi.Name);
            }
            if (oi.Index < 0)
            {
                return;
            }
            Devices.GPU.DrawKImage(KImages[oi.Index], filterColor, v3);
        }
        public void DrawCharacter(Scene scn, Character chr)
        {
            for (int i = 0; i < chr.Avatar.Length; i++)
            {
                Vector3 v3 = Util.Point2Vector3(Util.PointAddPoint(scn.Location, chr.Location));
                Devices.GPU.DrawKImage(chr.Avatar[i], Color.White, v3);
            }
        }
        public void DrawScene(Scene scn)
        {
            for (int i = 0; i < scn.LayerCount; i++)
            {
                for (int j = 0; j < scn[i].TileCount; j++)
                {
                    Vector3 v3 = Util.Point2Vector3(scn[i][j].DrawRectangle.Location);
                    v3 = Util.Vector3AddVector3(v3, Util.Point2Vector3(scn.Location));
                    if (scn[i][j].KImageIndexer != null)
                    {
                        DrawKImage(scn[i][j].KImageIndexer, Color.White, v3);
                    }
                    else
                    {
                        DrawKMovie(scn[i][j].KMovieIndexer, Color.White, v3);
                    }
                }
            }
        }
        //public void DrawKImage(ObjectIndexer poi, int img_index, Color filterColor, Vector3 v3)
        //{
        //    if (poi.Index < 0)
        //    {
        //        poi.Index = KImagePackages.GetIndex(poi.Name);
        //    }
        //    if (poi.Index < 0)
        //    {
        //        return;
        //    }
        //    Devices.GPU.DrawKImage(KImagePackages[poi.Index][img_index], filterColor, v3);
        //}
        //public void DrawKImage(KImage img, Color filterColor, Vector3 v3)
        //{
        //    Devices.GPU.DrawKImage(img, filterColor, v3);
        //}

        public void DrawKMovie(ObjectIndexer oi, Vector3 v3)
        {
            DrawKMovie(oi, Color.White, v3);
        }
        public void DrawKMovie(ObjectIndexer oi, Color filterColor, Vector3 v3)
        {
            if (oi.Index < 0)
            {
                oi.Index = KMovies.GetIndex(oi.Name);
            }
            if (oi.Index < 0)
            {
                return;
            }
            Devices.GPU.DrawKMovie(KMovies[oi.Index], filterColor, v3);
        }

        #region LoadTexture
        public void LoadAllTexture(string pathName, string extName)
        {
            List<string> dirName = new List<string>();
            Util.EnumDir(pathName, dirName);
            foreach (string pName in dirName)
            {
                DirectoryInfo di = new DirectoryInfo(pName);
                FileInfo[] fis = di.GetFiles(extName);
                foreach (FileInfo fi in fis)
                {
                    //Texture texture = LoadTexture(fi.FullName, 1);
                    //Textures.Add(fi.Name, texture);
                }
            }
        }

        //public void DrawKMovie(KMovie mov, Color color, Vector3 v3)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawKMovie(mov, color, v3);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawKMovie(mov, color, v3);
        //    }
        //}
        //public void DrawKMovie(KMovie mov, Color color, Size size, Vector3 v3)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawKMovie(mov, color, size, v3);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawKMovie(mov, color, size, v3);
        //    }
        //}
        //public void DrawKImage(KImage img, Color color, Vector3 v3)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawKImage(img, color, v3);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawKImage(img, color, v3);
        //    }
        //}
        //public void DrawKImage(KImage img, Color color, Size size, Vector3 v3)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawKImage(img, color, size, v3);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawKImage(img, color, size, v3);
        //    }
        //}
        //public void DrawText(string text, Color color, Point point)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawText(text, color, point);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawText(text, color, point);
        //    }
        //}
        //public void DrawText(string text, Brush brush, Point point)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawText(text, brush, point);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawText(text, brush, point);
        //    }
        //}
        //public void DrawText(string text, Color color, string fontName, int fontSize, FontStyle fontStyle, Point point)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawText(text, color, fontName, fontSize, fontStyle, point);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawText(text, color, fontName, fontSize, fontStyle, point);
        //    }
        //}
        //public void DrawText(string text, Brush brush, string fontName, int fontSize, FontStyle fontStyle, Point point)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawText(text, brush, fontName, fontSize, fontStyle, point);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawText(text, brush, fontName, fontSize, fontStyle, point);
        //    }
        //}
        //public void DrawText(string text, Brush brush, System.Drawing.Font font, Point point)
        //{
        //    if (Options.DrawMode == KGE.Define.DrawMode.GPU3D)
        //    {
        //        GPUDrawText(text, brush, font, point);
        //    }
        //    else if (Options.DrawMode == KGE.Define.DrawMode.CPU3D)
        //    {
        //        CPUDrawText(text, brush, font, point);
        //    }
        //}
        //#region GPU Draw
        //void GPUDrawKMovie(KMovie mov, Color color, Vector3 v3)
        //{
        //    double now = Devices.Timer.TotalSeconds;
        //    double ts = now - mov.LastUpdateTime;
        //    if (ts > mov.CurrentFrame.Length)
        //    {
        //        mov.LastUpdateTime = now;
        //        mov.FrameIncrease();
        //    }
        //    GPUDrawKImage(mov.CurrentFrame.KImage, color, mov.CurrentFrame.KImage.DrawRectangle.Size, v3);
        //}
        //void GPUDrawKMovie(KMovie mov, Color color, Size size, Vector3 v3)
        //{
        //    double now = Devices.Timer.TotalSeconds;
        //    double ts = now - mov.LastUpdateTime;
        //    if (ts > mov.CurrentFrame.Length)
        //    {
        //        mov.LastUpdateTime = now;
        //        mov.FrameIncrease();
        //    }
        //    GPUDrawKImage(mov.CurrentFrame.KImage, color, size, v3);
        //}

        //void GPUDrawKImage(KImage img, Color color, Vector3 v3)
        //{
        //    GPUDrawKImage(img, color, img.DrawRectangle.Size, v3);
        //}
        //void GPUDrawKImage(KImage img, Color color, Size size, Vector3 v3)
        //{
        //    //using (Texture texture = new Texture(Devices.D3DDev, img.Zone.Width, img.Zone.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed))
        //    //{
        //    //    using (Graphics g = texture.GetSurfaceLevel(0).GetGraphics())
        //    //    {
        //    //        //img.FlipHorizontal();
        //    //        g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
        //    //        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
        //    //        g.DrawImage(img.Image, new Point());
        //    //        v3.X += img.Zone.X;
        //    //        v3.Y += img.Zone.Y;
        //    //        GPUDrawTexture(texture, color, new Rectangle(new Point(), img.Zone.Size), size, v3);
        //    //    }
        //    //} 
        //    v3.X += img.DrawRectangle.X;
        //    v3.Y += img.DrawRectangle.Y;
        //    int i = Textures.GetIndex(img.Name);
        //    GPUDrawTexture(Textures[i], color, img.DrawRectangle, size, v3);
        //}

        //void GPUDrawText(string text, Color color, Point point)
        //{
        //    GPUDrawText(text, new SolidBrush(color), Devices.Font, point);
        //}
        //void GPUDrawText(string text, Brush brush, Point point)
        //{
        //    GPUDrawText(text, brush, Devices.Font, point);
        //}
        //void GPUDrawText(string text, Color color, string fontName, int fontSize, FontStyle fontStyle, Point point)
        //{
        //    GPUDrawText(text, new SolidBrush(color), fontName, fontSize, fontStyle, point);
        //}
        //void GPUDrawText(string text, Brush brush, string fontName, int fontSize, FontStyle fontStyle, Point point)
        //{
        //    GPUDrawText(text, brush, new System.Drawing.Font(fontName, fontSize, fontStyle, GraphicsUnit.Pixel), point);
        //}

        //void GPUDrawTexture(Texture img, Color color, Vector3 v3)
        //{
        //    int width = img.GetSurfaceLevel(0).Description.Width;
        //    int height = img.GetSurfaceLevel(0).Description.Height;
        //    GPUDrawTexture(img, color, new Rectangle(new Point(), new Size(width, height)), new Size(width, height), v3);
        //}
        //void GPUDrawTexture(Texture img, Color color, double zoom, Vector3 v3)
        //{
        //    int width = img.GetSurfaceLevel(0).Description.Width;
        //    int height = img.GetSurfaceLevel(0).Description.Height;
        //    double w = width * zoom;
        //    double h = height * zoom;
        //    GPUDrawTexture(img, color, new Size((int)w, (int)h), v3);
        //}
        //void GPUDrawTexture(Texture img, Color color, Size size, Vector3 v3)
        //{
        //    int width = img.GetSurfaceLevel(0).Description.Width;
        //    int height = img.GetSurfaceLevel(0).Description.Height;
        //    GPUDrawTexture(img, color, new Rectangle(new Point(), new Size(width, height)), size, v3);
        //}
        //void GPUDrawTexture(Texture img, Color color, Rectangle srcRect, Vector3 v3)
        //{
        //    GPUDrawTexture(img, color, srcRect, srcRect.Size, v3);
        //}
        //void GPUDrawTexture(Texture img, Color color, Rectangle srcRect, double zoom, Vector3 v3)
        //{
        //    double w = srcRect.Size.Width * zoom;
        //    double h = srcRect.Size.Height * zoom;
        //    GPUDrawTexture(img, color, srcRect, new Size((int)w, (int)h), v3);
        //}


        //public void GPUDrawImage(Image img, Color color, Vector3 v3)
        //{
        //    GPUDrawImage(img, color, new Rectangle(0, 0, img.Width, img.Height), new Size(img.Width, img.Height), v3);
        //}
        //public void GPUDrawImage(Image img, Color color, Rectangle srcRect, double zoom, Vector3 v3)
        //{
        //    int w = (int)(srcRect.Width * zoom);
        //    int h = (int)(srcRect.Height * zoom);
        //    GPUDrawImage(img, color, srcRect, new Size(w, h), v3);
        //}
        //public void GPUDrawImage(Image img, Color color, Rectangle srcRect, Size size, Vector3 v3)
        //{
        //    using (Texture texture = new Texture(Devices.D3DDev, img.Size.Width, img.Size.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed))
        //    {
        //        using (Graphics g = texture.GetSurfaceLevel(0).GetGraphics())
        //        {
        //            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
        //            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
        //            g.DrawImage(img, new Point());
        //            GPUDrawTexture(texture, color, srcRect, size, v3);
        //        }
        //    }
        //}
        //#endregion
        //#region CPU Draw
        //void CPUDrawKMovie(KMovie mov, Color color, Vector3 v3)
        //{
        //    double now = Devices.Timer.TotalSeconds;
        //    double ts = now - mov.LastUpdateTime;
        //    if (ts > mov.CurrentFrame.Length)
        //    {
        //        mov.LastUpdateTime = now;
        //        mov.FrameIncrease();
        //    }
        //    CPUDrawKImage(mov.CurrentFrame.KImage, color, mov.CurrentFrame.KImage.DrawRectangle.Size, v3);
        //}
        //void CPUDrawKMovie(KMovie mov, Color color, Size size, Vector3 v3)
        //{
        //    double now = Devices.Timer.TotalSeconds;
        //    double ts = now - mov.LastUpdateTime;
        //    if (ts > mov.CurrentFrame.Length)
        //    {
        //        mov.LastUpdateTime = now;
        //        mov.FrameIncrease();
        //    }
        //    CPUDrawKImage(mov.CurrentFrame.KImage, color, size, v3);
        //}

        //void CPUDrawKImage(KImage img, Color color, Vector3 v3)
        //{
        //    CPUDrawKImage(img, color, img.DrawRectangle.Size, v3);
        //}
        //void CPUDrawKImage(KImage img, Color color,Size size, Vector3 v3)
        //{
        //    v3.X += img.DrawRectangle.X;
        //    v3.Y += img.DrawRectangle.Y;
        //    int i = Textures.GetIndex(img.Name);
        //    CPUDrawImage(Image.FromStream(new MemoryStream(img.Data)), color, new Rectangle(new Point(), img.DrawRectangle.Size), size, v3);
        //}

        //void CPUDrawText(string text, Color color, Point point)
        //{
        //    CPUDrawText(text, new SolidBrush(color), Devices.Font, point);
        //}
        //void CPUDrawText(string text, Brush brush, Point point)
        //{
        //    CPUDrawText(text, brush, Devices.Font, point);
        //}
        //void CPUDrawText(string text, Color color, string fontName, int fontSize, FontStyle fontStyle, Point point)
        //{
        //    CPUDrawText(text, new SolidBrush(color), fontName, fontSize, fontStyle, point);
        //}
        //void CPUDrawText(string text, Brush brush, string fontName, int fontSize, FontStyle fontStyle, Point point)
        //{
        //    CPUDrawText(text, brush, new System.Drawing.Font(fontName, fontSize, fontStyle, GraphicsUnit.Pixel), point);
        //}
        //void CPUDrawText(string text, Brush brush, System.Drawing.Font font, Point point)
        //{
        //    if (font != Devices.Font)
        //    {
        //        Devices.Font.Dispose();
        //        Devices.Font = font;
        //    }

        //    string[] texts = text.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.None);
        //    int longest = 0;
        //    foreach (string str in texts)
        //    {
        //        if (str.Length > longest)
        //        {
        //            longest = str.Length;
        //        }
        //    }

        //    Graphics g = Graphics.FromImage(Devices.Surface);
        //    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
        //    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

        //    for (int i = 0; i < texts.Length; i++)
        //    {
        //        g.DrawString(texts[i], font, brush, point.X, point.Y + i * font.Size);
        //    }
        //    NeedCPUDraw = true;
        //    NeedCPUClear = true;
        //}

        //void CPUDrawImage(Image img, Color color, Vector3 v3)
        //{
        //    int width = img.Width;
        //    int height = img.Height;
        //    CPUDrawImage(img, color, new Rectangle(new Point(), new Size(width, height)), new Size(width, height), v3);
        //}
        //void CPUDrawImage(Image img, Color color, double zoom, Vector3 v3)
        //{
        //    int width = img.Width;
        //    int height = img.Height;
        //    double w = width * zoom;
        //    double h = height * zoom;
        //    CPUDrawImage(img, color, new Size((int)w, (int)h), v3);
        //}
        //void CPUDrawImage(Image img, Color color, Size size, Vector3 v3)
        //{
        //    int width = img.Width;
        //    int height = img.Height;
        //    CPUDrawImage(img, color, new Rectangle(new Point(), new Size(width, height)), size, v3);
        //}
        //void CPUDrawImage(Image img, Color color, Rectangle srcRect, Vector3 v3)
        //{
        //    CPUDrawImage(img, color, srcRect, srcRect.Size, v3);
        //}
        //void CPUDrawImage(Image img, Color color, Rectangle srcRect, double zoom, Vector3 v3)
        //{
        //    double w = srcRect.Size.Width * zoom;
        //    double h = srcRect.Size.Height * zoom;
        //    CPUDrawImage(img, color, srcRect, new Size((int)w, (int)h), v3);
        //}
        //void CPUDrawImage(Image img, Color color, Rectangle srcRect, Size size, Vector3 v3)
        //{
        //    //img.RotateFlip(RotateFlipType.RotateNoneFlipX);
        //    Graphics g = Graphics.FromImage(Devices.Surface);
        //    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
        //    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
        //    g.DrawImage(img, new Rectangle(new Point((int)v3.X, (int)v3.Y), size), srcRect, GraphicsUnit.Pixel); 

        //    NeedCPUDraw = true;
        //    NeedCPUClear = true;
        //}

        //void CPUClear()
        //{
        //    Graphics g = Graphics.FromImage(Devices.Surface);
        //    g.Clear(Color.Transparent);
        //    //NeedCPUClear = false;
        //}
        //void CPUDrawLine(Pen pen, Point p1, Point p2)
        //{
        //    Graphics g = Graphics.FromImage(Devices.Surface);
        //    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
        //    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
        //    g.DrawLine(pen, p1, p2);
        //    NeedCPUDraw = true;
        //    NeedCPUClear = true;
        //}
        #endregion
        #endregion
    }
}
